home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / hypercrd / frtxt103.hqx / master FT v1.03 / Free Text XFCN Source Code / openCloseFiles 0.7.c < prev    next >
Text File  |  1990-01-27  |  9KB  |  397 lines

  1. /* openCloseFiles ([params]) XFCN source code
  2.  * copyright 1990 - Mark Zimmermann
  3.  *
  4.  * - specially modified (for potential CD-ROM applications) -- so that it can:
  5.  *    1) open any file types, not just TEXT and CTLZ, for database & indices
  6.  *    2) ask for location of the index file(s) if not found in same folder
  7.  *        as the main file, with the suffix '.k' or '.p'
  8.  *
  9.  * Call this XFCN as 'openCloseFiles([optional list of numbers here])'.
  10.  *
  11.  * If the XFCN is called with no arguments, it puts up the standard files
  12.  * dialog box and gives back in return the file refNums for the main
  13.  * (document/database) file, *.k, and *.p files, on one line, in
  14.  * that order, separated by spaces.  The XFCN also returns, on a second
  15.  * line, the file name of the file that has been opened.
  16.  *
  17.  * If the XFCN is passed any numerical parameters, it attempts to
  18.  * close them (assuming they are file refNums) and doesn't try to
  19.  * open anything....
  20.  *
  21.  * If an error while opening a file seems to occur, the XFCN attempts
  22.  * to close all files that have already been opened, and returns with
  23.  * an error msg instead of the three file refNums.  No error checking
  24.  * is done on closing files, since there's not much that one could
  25.  * do about such an error in any case....
  26.  *
  27.  */
  28.  
  29.  
  30. #include <MacTypes.h>
  31. #include <FileMgr.h>
  32. #include <StdFilePkg.h>
  33. #include <HyperXCmd.h>
  34. #include <SetUpA4.h>
  35.  
  36. #define NULL  0
  37.  
  38.  
  39. pascal void main (XCmdBlockPtr paramPtr);
  40. int zGetFile (Str255 *fileNamePtr, int *volRefNumPtr, long fileType);
  41. void give_msg (char *msg);
  42. void returnErrorMsg (XCmdBlockPtr paramPtr, char *msg);
  43. long atol (char *s);
  44. void ltoaR (char *ansp, long n, int maxDigits);
  45. int strlen (char *s);
  46. char *strcpy (char *s1, char *s2);
  47.  
  48.  
  49. pascal void main (paramPtr)
  50.   XCmdBlockPtr paramPtr;
  51.   {
  52.     Str255 fileName;
  53.     int refNum, volRefNum, textFileRefNum, keyFileRefNum, ptrFileRefNum,
  54.         i, errNum;
  55.     Handle answer;
  56.     WindowRecord w_record;
  57.     WindowPtr info_window;
  58.     Rect b_rect;
  59.  
  60.     RememberA0 ();
  61.     SetUpA4();
  62.     if (paramPtr->paramCount != 0)
  63.       {
  64.         for (i = 0; i < paramPtr->paramCount; ++i)
  65.           {
  66.             refNum = atol (*(paramPtr->params[i]));
  67.             FSClose (refNum);
  68.           }
  69.         RestoreA4();
  70.         return;
  71.       }
  72.  
  73.     /* set up a window to give user feedback during file opening... */
  74.     b_rect.top = 30;
  75.     b_rect.left = 12;
  76.     b_rect.bottom = 332;
  77.     b_rect.right = 500;
  78.     info_window = NewWindow (&w_record, &b_rect, "\p", (Boolean)1,
  79.         dBoxProc, (WindowPtr)-1, (Boolean)0, (long)0);
  80.     ShowWindow (info_window);
  81.     SetPort (info_window);
  82.     TextFont (0);
  83.     give_msg ("\pPlease choose a database (indexed file) to open...");
  84.  
  85.     /* note that file type 'TEXT' is now ignored here! */
  86.     if (! zGetFile (&fileName, &volRefNum, 'TEXT'))
  87.       {
  88.         DisposeWindow (info_window);
  89.         RestoreA4();
  90.         return;
  91.       }
  92.  
  93.     errNum = FSOpen (&fileName, volRefNum, &textFileRefNum);
  94.     if (errNum != noErr && errNum != opWrErr)
  95.       {
  96.         returnErrorMsg (paramPtr,
  97.               "{Sorry, error in opening database file!}");
  98.         DisposeWindow (info_window);
  99.         RestoreA4();
  100.         return;
  101.       }
  102.  
  103.     *(fileName + *fileName + 1) = '.';
  104.     *(fileName + *fileName + 2) = 'k';
  105.     *fileName += 2;
  106.     errNum = FSOpen (&fileName, volRefNum, &keyFileRefNum);
  107.     if (errNum != noErr && errNum != opWrErr)
  108.       {
  109.         SysBeep (10);
  110.         give_msg ("\p");
  111.         give_msg ("\pSorry, can't find the index key ('.k') file for this database!");
  112.         give_msg ("\pPlease locate it, or cancel...");
  113.         
  114.         /* note that file type 'CTLZ' is now ignored here! */
  115.         if (! zGetFile (&fileName, &volRefNum, 'CTLZ'))
  116.           {
  117.             FSClose (textFileRefNum);
  118.             DisposeWindow (info_window);
  119.               RestoreA4();
  120.               return;
  121.             }
  122.           else
  123.             {
  124.             errNum = FSOpen (&fileName, volRefNum, &keyFileRefNum);
  125.             if (errNum != noErr && errNum != opWrErr)
  126.               {
  127.                 FSClose (textFileRefNum);
  128.                   returnErrorMsg (paramPtr,
  129.                         "{Sorry, error in opening index key ('.k') file!}");
  130.                 DisposeWindow (info_window);
  131.                   RestoreA4();
  132.                   return;
  133.                 }
  134.             }
  135.       }
  136.  
  137.     *(fileName + *fileName) = 'p';
  138.     errNum = FSOpen (&fileName, volRefNum, &ptrFileRefNum);
  139.     if (errNum != noErr && errNum != opWrErr)
  140.       {
  141.         SysBeep (10);
  142.         give_msg ("\p");
  143.         give_msg ("\pSorry, can't find the index ptr ('.p') file for this database!");
  144.         give_msg ("\pPlease locate it, or cancel...");
  145.         
  146.         /* note that file type 'CTLZ' is now ignored here! */
  147.         if (! zGetFile (&fileName, &volRefNum, 'CTLZ'))
  148.           {
  149.             FSClose (textFileRefNum);
  150.             FSClose (keyFileRefNum);
  151.             DisposeWindow (info_window);
  152.               RestoreA4();
  153.               return;
  154.             }
  155.           else
  156.             {
  157.             errNum = FSOpen (&fileName, volRefNum, &ptrFileRefNum);
  158.             if (errNum != noErr && errNum != opWrErr)
  159.               {
  160.                 FSClose (textFileRefNum);
  161.                 FSClose (keyFileRefNum);
  162.                   returnErrorMsg (paramPtr,
  163.                         "{Sorry, error in opening index ptr ('.p') file!}");
  164.                 DisposeWindow (info_window);
  165.                   RestoreA4();
  166.                   return;
  167.                 }
  168.             }
  169.       }
  170.  
  171.     if ((answer = NewHandle (64)) == NULL)
  172.       {
  173.         FSClose (textFileRefNum);
  174.         FSClose (keyFileRefNum);
  175.         FSClose (ptrFileRefNum);
  176.           returnErrorMsg (paramPtr,
  177.             "{Sorry, bad out of memory error in XFCN openFiles call!}");
  178.         DisposeWindow (info_window);
  179.           RestoreA4();
  180.           return;
  181.       }
  182.  
  183.     ltoaR (*answer, textFileRefNum, 6);
  184.     ltoaR (*answer + 6, keyFileRefNum, 6);
  185.     ltoaR (*answer + 12, ptrFileRefNum, 6);
  186.     *(*answer + 18) = '\r';
  187.     for (i = 1; i <= *fileName - 2; ++i)
  188.         *(*answer + 18 + i) = fileName[i];
  189.     *(*answer + 18 + i) = '\0';
  190.  
  191.     paramPtr->returnValue = answer;
  192.     DisposeWindow (info_window);
  193.     RestoreA4();
  194.     return;
  195.   }
  196.  
  197.  
  198. /* this routine does the standard files dialog to get the name of the main file
  199.  * of the database; other file names are gotten from that by putting
  200.  * a '.k' or a '.p' at the end.  This routine returns 1 if all is well,
  201.  * or 0 if the user cancels out...
  202.  *
  203.  * special mod to open any file, not just type text...keep the myFileTypes
  204.  * parameter in there, even though it's not used any more....who knows when
  205.  * it might come in handy?!
  206.  */
  207.  
  208. int zGetFile (fileNamePtr, volRefNumPtr, fileType)
  209.   Str255 *fileNamePtr;
  210.   int *volRefNumPtr;
  211.   long fileType;
  212.   {
  213.     SFTypeList myFileTypes;
  214.     Point SFGwhere;
  215.     SFReply myReply;
  216.     register int i;
  217.  
  218.     SFGwhere.v = 90;
  219.     SFGwhere.h = 82;
  220.     myFileTypes[0] = fileType;
  221.     
  222.     /* main change is to put in the '-1' here to signify that file
  223.      *    type doesn't matter to SFGetFile
  224.      */
  225.     SFGetFile (SFGwhere, "\p", 0L, -1, myFileTypes, 0L, &myReply);
  226.     
  227.     if (myReply.good)
  228.       {
  229.         for (i = *myReply.fName; i >= 0; --i)
  230.             (*fileNamePtr)[i] = myReply.fName[i];
  231.         *volRefNumPtr = myReply.vRefNum;
  232.         return (1);
  233.       }
  234.     else
  235.         return (0);
  236.   }
  237.  
  238.  
  239. /* tiny routine to put a message into my message window.... takes in a
  240.  * PASCAL type string and displays it nicely....
  241.  */
  242.  
  243. void give_msg (msg)
  244.   char *msg;
  245.   {
  246.     Rect b_rect;
  247.     RgnHandle theRgn;
  248.     
  249.     b_rect.top = b_rect.left = 0;
  250.     b_rect.bottom = 302;
  251.     b_rect.right = 488;
  252.     
  253.     theRgn = NewRgn ();
  254.     ScrollRect (&b_rect, 0, -15, theRgn);
  255.     DisposeRgn (theRgn);
  256.     
  257.     MoveTo (4, 295);
  258.     DrawString (msg);
  259.     
  260.     return;
  261.   }
  262.  
  263.  
  264. /* function to set the return value of the XFCN to a chosen error msg;
  265.  * if there isn't enough free memory to give us a Handle to the msg,
  266.  * beep a bit and then return!
  267.  */
  268.  
  269. void returnErrorMsg (paramPtr, msg)
  270.   XCmdBlockPtr paramPtr;
  271.   char *msg;
  272.   {
  273.     Handle answer;
  274.     int msgLength;
  275.     
  276.     SysBeep (10);
  277.     msgLength = strlen (msg);
  278.     if ((answer = NewHandle (1 + msgLength)) == NULL)
  279.       {
  280.         SysBeep (10);
  281.         SysBeep (10);
  282.         return;
  283.       }
  284.  
  285.     strcpy (*answer, msg);
  286.     paramPtr->returnValue = answer;
  287.     return;
  288.   }
  289.  
  290.  
  291. /* function to convert alphanumeric string to a long int, from K&R...
  292.  */
  293.  
  294. long atol (s)
  295.   register char *s;
  296.   {
  297.     int signflag = 0;
  298.     register long r = 0;
  299.  
  300.     while (*s == ' ')
  301.         s++;
  302.         
  303.     if (*s == '-')
  304.       {
  305.         signflag = 1;
  306.         s++;
  307.       }
  308.     else if (*s == '+')
  309.          s++;
  310.  
  311.     while (*s >= '0' && *s <= '9') 
  312.         r = r * 10 + (*s++ - '0');
  313.     
  314.     return (signflag ? -r : r);
  315. }
  316.  
  317.  
  318. /* function to convert a number into a string of width maxDigits and
  319.  * store it right-justified, blank-filled on left; based on K&R p. 60
  320.  * example of itoa().
  321.  *
  322.  * Error handling:  put a '>' or '<' in leading place to warn of an
  323.  * overflow (no room for digits on a positive or negative number,
  324.  * respectively), and put a '^' in leading place to warn if no room
  325.  * for '-' sign on negative number...
  326.  */
  327.  
  328. void ltoaR (ansp, n, maxDigits)
  329.   register char *ansp;
  330.   register long n;
  331.   int maxDigits;
  332.   {
  333.     register int i;
  334.     long sign;
  335.     
  336.     i = maxDigits - 1;
  337.     if ((sign = n) < 0)
  338.         n = -n;
  339.     
  340.     do
  341.       {
  342.           ansp[i--] = n % 10 + '0';
  343.       }
  344.     while ((n /= 10) > 0 && i >= 0);
  345.     
  346.     if (i < 0 && n > 0)        /* ran out of room with digits still to go */
  347.       {
  348.         if (sign > 0)
  349.             ansp[0] = '>';            /* positive overflow signal */
  350.         else
  351.             ansp[0] = '<';            /* negative overflow signal */
  352.       }
  353.     else
  354.       {
  355.         if (sign < 0)
  356.             if (i >= 0)
  357.                 ansp[i--] = '-';
  358.             else
  359.                 ansp[0] = '^';        /* no room for '-' sign signal */
  360.         for ( ; i >= 0; --i)
  361.             ansp[i] = ' ';
  362.       }
  363.  
  364.     return;
  365.   }
  366.   
  367.  
  368. /* function to determine the length of a string ... standard thing,
  369.  * adapted from K&R p.98 ....
  370.  */
  371.  
  372. int strlen (s)
  373.   register char *s;
  374.   {
  375.     char *s0 = s;
  376.  
  377.     while (*s++)
  378.         ;
  379.     return (s - s0 - 1);
  380.   }
  381.  
  382.  
  383. /* function to copy a string from one place to another, in a rather
  384.  * obvious fashion ... adapted from K&R p.101 ....
  385.  */
  386.  
  387. char *strcpy (s1, s2)
  388.   register char *s1, *s2;
  389.   {
  390.     char *s = s1;
  391.     
  392.     while (*s1++ = *s2++)
  393.         ;
  394.     return (s);
  395.   }
  396.  
  397.